package com.yt.server.mode.core;

import java.util.HashMap;
import java.util.Map;

import com.yt.server.mode.api.IFunction;
import com.yt.server.mode.api.IModel;
import com.yt.server.mode.api.INotification;
import com.yt.server.mode.api.IObserver;
import com.yt.server.mode.api.IProxy;
import com.yt.server.mode.patterns.observer.Observer;

/**
 * 模型层
 */
public class Model implements IModel {

	protected static Model instance;

	protected Controller controller;

	protected Map<String, IProxy> proxyMap;

	protected Model() {
		instance = this;
		proxyMap = new HashMap<String, IProxy>();
		initializeModel();
	}

	protected void initializeModel() {
		controller = Controller.getInstance();
	}

	public synchronized static Model getInstance() {
		if (instance == null)
			instance = new Model();

		return instance;
	}

	public void registerProxy(final IProxy proxy) {
		if (this.proxyMap.containsKey(proxy.getProxyName()))
			return;
		this.proxyMap.put(proxy.getProxyName(), proxy);

		String[] noteInterests = proxy.listNotificationInterests();
		if (null != noteInterests) {
			IFunction function = new IFunction() {
				public void onNotification(INotification notification) {
					proxy.handleNotification(notification);
				}
			};
			IObserver observer = new Observer(function, proxy);

			for (int i = 0; i < noteInterests.length; i++)
				if (controller != null)
					controller.registerObserver(noteInterests[i], observer);
		}
		proxy.onRegister();
	}

	public IProxy removeProxy(String proxyName) {
		IProxy proxy = (IProxy) this.proxyMap.get(proxyName);
		if (proxy != null) {

			String[] noteInterests = proxy.listNotificationInterests();

			for (int i = 0; i < noteInterests.length; i++)
				if (controller != null)
					controller.removeObserver(noteInterests[i], proxy);

			proxy.onRemove();
			return proxyMap.remove(proxyName);
		}
		return null;
	}

	public IProxy retrieveProxy(String proxy) {
		return (IProxy) this.proxyMap.get(proxy);
	}

	public boolean hasProxy(String proxyName) {
		return proxyMap.containsKey(proxyName);
	}
}
